/**
 *
 */
package jdk8;

import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.SynchronousQueue;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.ObjLongConsumer;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import cn.hutool.core.collection.CollUtil;
import com.google.common.collect.Streams;
import guava.ListsUtils;
import org.eclipse.collections.impl.utility.Iterate;
import org.junit.Test;

/**
 * @Title:
 * @author zhoujie
 * @date 2018年6月1日 上午10:26:13
 *
 */
public class StreamTest {
    /**
     * Stream 的 sorted返回的是一个新的list
     * Collections.sort 则是修改原来的
     */
    @Test
    public void test01() {

        Stream<String> list = Stream.of("1", "5", "3", "4").sorted((v1, v2) -> v1.compareTo(v2));
        list.forEach(System.out::printf);
        System.out.println("");
        List<String> list2 = Arrays.asList("1", "5", "3", "4");
        Collections.sort(list2, (v1, v2) -> v1.compareTo(v2));
        list2.forEach(System.out::printf);
    }

    /**
     * 第三个参数表示重复的处理方式
     * 第四个参数 使用map的什么实现类
     * (v1,v2)->v2) 取后者 v1 取前者
     * toMap
     */
    @Test
    public void test02() {
        List<User> users = Arrays.asList(new User(1, "sky"), new User(1, "张三"), new User(3, "李四"));
        Map<Integer, User> musers = users.stream().collect(Collectors.toMap(User::getId, Function.identity(), (v1, v2) -> v2, TreeMap::new));
        System.out.println(musers);
    }

    /**
     * groupingBy
     * 分组
     */
    @Test
    public void test03() {
        List<User> users = Arrays.asList(new User(1, "sky"), new User(1, "张三"), new User(3, "李四"));
        Map<Integer, List<User>> gUsers = users.stream().collect(Collectors.groupingBy(User::getId));
        System.out.println(gUsers);
    }


    /**
     * groupingBy
     * 分组并求每个组最大id的人
     */
    @Test
    public void test04() {
        List<User> users = Arrays.asList(new User(1, 18, "sky"), new User(1, 20, "张三"), new User(3, 21, "李四"));
        // Map<Integer, List<User>> gUsers=users.stream().collect(Collectors.groupingBy(User::getId,Collectors.maxBy((v1,v2)->v2)));

        // System.out.println(gUsers);
    }


    /**
     * groupingBy
     * 求每个字符串出现的次数并且按出现次数从大到小排序输出
     */
    @Test
    public void test05() {

        //Map<String, Long> finalMap = new LinkedHashMap<>();
        String[] names = {"张三", "张三", "李四", "李四", "李四", "李四", "王五"};
        Map<String, Long> finalMap = Stream.of(names).collect(Collectors.groupingBy(Function.identity(), Collectors.counting())).entrySet().stream().sorted((v1, v2) -> v2.getValue().compareTo(v1.getValue())).collect(Collectors.toMap(Entry::getKey, Entry::getValue, (v1, v2) -> v2, LinkedHashMap::new));
        // Map<Integer, List<User>> gUsers=users.stream().collect(Collectors.groupingBy(User::getId,Collectors.maxBy((v1,v2)->v2)));
        //gmap.entrySet().stream().sorted((v1,v2)->v2.getValue().compareTo(v2.getValue())).forEach(e -> finalMap.put(e.getKey(), e.getValue()));
		/*gmap.entrySet().stream()
        .sorted(Map.Entry.<String, Long>comparingByValue()
        .reversed()).forEachOrdered(e -> finalMap.put(e.getKey(), e.getValue()));*/
        System.out.println(finalMap);
    }

    /**
     * jdk8
     * 求每个字符串出现的次数并且按出现次数从大到小排序输出
     */
    @Test
    public void test06() {
        String[] names = {"张三", "张三", "李四", "李四", "李四", "李四", "王五", "A", "B", "C", "C"};
        Map<String, Long> finalMap = Stream.of(names)
                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())).entrySet().stream()
                .sorted((v1, v2) -> v2.getValue().compareTo(v1.getValue()))
                .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (v1, v2) -> v2, LinkedHashMap::new));
        System.out.println(finalMap);
    }

    /**
     * 按id分组 如果id相同里面的名字用逗号隔开
     */
    @Test
    public void test07() {
        List<User> users = Arrays.asList(new User(1, "sky"), new User(1, "张三"), new User(3, "李四"), new User(1, "张三"));

        Map<Integer, String> finalMap = users.stream().collect(Collectors.groupingBy(User::getId, Collectors.mapping(User::getName, Collectors.joining(",", "(", ")"))));

        //去重复名字
        Map<Integer, Set<String>> finalMap2 = users.stream().collect(Collectors.groupingBy(User::getId, Collectors.mapping(User::getName, Collectors.toSet())));
        List<Map<Integer, String>> list = finalMap2.entrySet().stream().map(s -> {
            Map<Integer, String> m = new HashMap<>();
            m.put(s.getKey(), s.getValue().stream().collect(Collectors.joining(",")));
            return m;
        }).collect(Collectors.toList());
        //System.out.println(Stream.of("a", "b", "c").collect(Collectors.joining(",")));
        System.out.println(finalMap);
        System.out.println(finalMap2);
        System.out.println(list);
    }

    @Test
    public void test08() {
        //指定转换成具体实现类的集合
        TreeSet<Integer> collect2 = Stream.of(1, 3, 4).collect(Collectors.toCollection(TreeSet::new));
        //转map
        Map<Integer, Integer> collect1 = Stream.of(1, 3, 4).collect(Collectors.toMap(x -> x, x -> x + 1));
        //平均值
        //System.out.println(Stream.of(1, 2, 3).collect(Collectors.averagingInt(x->x)));
        //最大值
        System.out.println(Stream.of(1, 2, 3).collect(Collectors.maxBy(Integer::compare)).get());
        //最小值
        System.out.println(Stream.of(1, 2, 3).collect(Collectors.minBy(Integer::compare)).get());

        Map<Boolean, List<Integer>> collect5 = Stream.of(1, 3, 4).collect(Collectors.partitioningBy(x -> x > 2));
        System.out.println(collect5);
        Map<Boolean, Long> collect4 = Stream.of(1, 3, 4).collect(Collectors.partitioningBy(x -> x > 2, Collectors.counting()));
        System.out.println(collect4);
        //Collectors.reducing(0, x -> x + 1, (x, y) -> x + y))：在求累计值的时候，还可以对参数值进行改变，这里是都+1后再求和。跟reduce方法有点类似，但reduce方法没有第二个参数。
        //System.out.println(Stream.of(1, 3, 4).collect(Collectors.reducing(0, x -> x * 2, (x, y) -> x + y)));

        String str = Stream.of("a", "b", "c", "a").collect(Collectors.collectingAndThen(Collectors.joining(","), x -> "(" + x + ")"));
        String str2 = Stream.of("a", "b", "c", "a").collect(Collectors.joining(",", "(", ")"));

        System.out.println(str);
        System.out.println(str2);
    }

    @Test
    public void test09() {
        Stream.of("one", "two", "three", "four")
                .filter(e -> e.length() > 3)
                .peek(e -> System.out.println("Filtered value: " + e))
                .map(String::toUpperCase)
                .peek(e -> System.out.println("Mapped value: " + e))
                .collect(Collectors.toList());
    }

    @Test
    public void test10() {
        System.out.println("都大于8？" + Stream.of(1, 2, 4, 5, 5, 8, 9).allMatch(d -> d > 8));
        System.out.println("其中一个大于8？" + Stream.of(1, 2, 4, 5, 5, 8, 9).anyMatch(d -> d > 8));
    }

    @Test
    public void test11(){
        List<Integer> nums = Stream.of(1, 2, 4, 5, 5, 8, 9).collect(Collectors.toList());
        nums.removeIf(n->n==9);
        //removeIf
        System.out.println(nums);
    }

    @Test
    public void test12(){
        List<Integer> nums = Stream.of(1, 2, 4, 5, 5, 8, 9).collect(Collectors.toList());
        Stream<Integer> integerStream = Streams.mapWithIndex(Stream.of(1, 2, 4, 5, 5, 8, 9), (item, index) -> {
            System.out.println("item:" + item + "  index:" + index);
            return 2;
        });

    }

    @Test
    public  void test13(){
        CollUtil.forEach(Arrays.asList("1","3").iterator(),(item, i)->{
            System.out.println("item:"+item+" i:"+i);
        });
    }
}
